#pragma once

#include <vector>
#include <map>

#include "dcmtk/dcmdata/dcdatset.h"

#include "idataset.h"


class DataSet final
    :public IDataSet
{
public:
    DataSet::DataSet();

    DataSet::~DataSet();

public:
    DcmDataset*
    GetDataSet()
    override;

    bool
    ParseIODString(
        const std::string& aJsonString
    ) override;

    bool
    GeneralDCMFile(
        const std::string& aFilePath,
        DCM_TransferSyntax aXfer
    ) override;

    bool
    LoadDCMFile(
        const std::string& aFilePath
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const float aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const signed short aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const signed int aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const unsigned int aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const signed short* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const unsigned int* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const float* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const double* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const std::string& aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const unsigned short aValue
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const unsigned char* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const unsigned short* aValue,
        const unsigned long aCount
    ) override;

    bool
    Set(
        const std::string& aFieldName
    ) override;

    bool
    Set(
        const std::string& aFieldName,
        const double aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const float aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const signed short aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const signed int aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const unsigned int aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const signed short* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const unsigned int* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const float* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const double* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const unsigned char* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const unsigned short* aValue,
        const unsigned long aCount
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const double aValue
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName
    ) override;

    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const unsigned short aValue
    ) override;


    bool
    SetPrivate(
        const std::string& aFieldName,
        const std::string& aPrivateName,
        const std::string& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        float& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        double& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        unsigned int& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        unsigned short& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        signed short& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        std::string& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        signed int& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const unsigned char*& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const float*& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const double*& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const unsigned int*& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const unsigned short*& aValue
    ) override;

    bool
    Get(
        const std::string& aFieldName,
        const signed short*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        unsigned short& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        std::string& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        float& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        double& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        unsigned int& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        signed short& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        signed int& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const unsigned char*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const float*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const double*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const unsigned int*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const unsigned short*& aValue
    ) override;

    bool
    GetPrivate(
        const std::string& aFieldName,
        std::string& aPrivateCreator,
        const signed short*& aValue
    ) override;

private:
    void
    PrivSubParseIODFile(
        const std::string& aStr
    );

private:
    DcmDataset*                                            myDataSet;
    std::map<std::string, std::vector<unsigned short>>     myTags;
};
